#include "texture.hpp"
#include "engine.hpp"
#include "sdltool.hpp"

namespace sdl_engine {

Texture Texture::Null(nullptr);

Texture::Texture(u32 format, int access, const Size& size) {
    texture_ = SDL_CreateTexture(
            engine.GetRenderer().Raw(),
            format, access,
            size.w, size.h
            );
    if (!texture_) {
        LogeWithSDLErr("Texture create failed");
    } else {
        size_ = size;
    }
}

Texture::Texture(SDL_Surface* surface) {
    if (!surface) {
        Logw("surface is nullptr");
    } else {
        texture_ = SDL_CreateTextureFromSurface(engine.GetRenderer().Raw(),
                                                surface);
        if (!texture_) {
            LogeWithSDLErr("Texture create from surface failed");
        } else {
            size_.w = surface->w;
            size_.h = surface->h;
        }
    }
}

Texture::Texture(const std::string& filename) {
    texture_ = IMG_LoadTexture(engine.GetRenderer().Raw(), filename.c_str());
    if (!texture_) {
        LogeWithSDLErr(
            Fmt("While loading %s: create texture failed",
                filename.c_str()));
    } else {
        SDL_QueryTexture(texture_, nullptr, nullptr, &size_.w, &size_.h);
    }
}

Texture::Texture(const std::string& filename, const Color& keyColor) {
    auto surface = IMG_Load(filename.c_str());
    if (!surface) {
        LogeWithSDLImageErr(
            Fmt("Load image %s failed: create surface failed",
                filename.c_str()));
    } else {
        size_.w = surface->w;
        size_.h = surface->h;
        SDL_SetColorKey(surface, true, SDL_MapRGBA(surface->format,
                                                   keyColor.r,
                                                   keyColor.g,
                                                   keyColor.b,
                                                   keyColor.a));
        texture_ = SDL_CreateTextureFromSurface(engine.GetRenderer().Raw(),
                                                surface);
        if (!texture_) {
            LogeWithSDLErr(
                Fmt("Load image %s failed: create texture failed",
                    filename.c_str()));
        }
        SDL_FreeSurface(surface);
    }
}

Texture::~Texture() {
    SDL_DestroyTexture(texture_);
}


SubTexture SubTexture::Null(nullptr, rect(0, 0, 0, 0));

SubTexture::SubTexture(Texture* texture, const Rect& rect)
    : texture_(texture), rect_(rect) {}

}
